import type {
  AddReq,
  DelReq,
  InfoReq,
  UserPageRes,
} from '@fast-crud/fast-crud';

import type { AxiosRequestConfig, AxiosResponse } from '@vben/request';
import type { Recordable } from '@vben/types';

import type { DefGenTableModel } from './model/defGenTableModel';

import type { PageParams, PageResult } from '#/api/types';
import type { TemplateEnum } from '#/enums/system';

import qs from 'qs';

import { requestClient } from '#/api/request';
import { ServicePrefixEnum } from '#/enums/commonEnum';
import { ContentTypeEnum, RequestEnum } from '#/enums/httpEnum';

const MODULAR = 'defGenTable';
const ServicePrefix = ServicePrefixEnum.GENERATOR;

export const DefGenTableConfig = {
  Save: {
    url: `${ServicePrefix}/${MODULAR}`,
    method: RequestEnum.POST,
  } as AxiosRequestConfig,
  Update: {
    url: `${ServicePrefix}/${MODULAR}`,
    method: RequestEnum.PUT,
  },
};

export namespace DefGenTableApi {
  /**
   * 分页查询
   */
  export async function page(
    params: PageParams<DefGenTableModel.DefGenTablePageQuery>,
  ) {
    return requestClient.post<PageResult<DefGenTableModel.DefGenTableResultVO>>(
      `${ServicePrefix}/${MODULAR}/page`,
      params,
    );
  }

  export async function query(params?: DefGenTableModel.DefGenTablePageQuery) {
    return requestClient.post<DefGenTableModel.DefGenTableResultVO[]>(
      `${ServicePrefix}/${MODULAR}/query`,
      params,
    );
  }

  export async function save(params: DefGenTableModel.DefGenTableSaveVO) {
    return requestClient.post<DefGenTableModel.DefGenTableResultVO>(
      DefGenTableConfig.Save.url as string,
      params,
    );
  }

  export async function update(params: DefGenTableModel.DefGenTableUpdateVO) {
    return requestClient.put<DefGenTableModel.DefGenTableResultVO>(
      DefGenTableConfig.Update.url as string,
      params,
    );
  }
  export async function remove(data: string[]) {
    return requestClient.delete<boolean>(`${ServicePrefix}/${MODULAR}`, {
      data,
    });
  }

  export const downloadZip = (ids: string[], template: string) =>
    requestClient.download<AxiosResponse<Blob>>(
      `${ServicePrefix}/${MODULAR}/downloadZip?${qs.stringify({ ids, template }, { arrayFormat: 'repeat' })}`,
      {
        responseReturn: 'raw',
      },
    );

  export async function selectTableList(
    params: PageParams<DefGenTableModel.DefGenTablePageQuery>,
  ) {
    return requestClient.post<DefGenTableModel.DefGenTableResultVO[]>(
      `${ServicePrefix}/${MODULAR}/selectTableList`,
      params,
      { timeout: 60_000 },
    );
  }

  export async function findTableList(params: string[]) {
    return requestClient.post<DefGenTableModel.DefGenTableResultVO[]>(
      `${ServicePrefix}/${MODULAR}/findTableList`,
      params,
    );
  }

  export async function previewCode(id: string, template: string) {
    return requestClient.post<Record<string, string>>(
      `${ServicePrefix}/${MODULAR}/previewCode`,
      { id, template },
      {
        headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
      },
    );
  }

  export async function generatorCode(params: DefGenTableModel.DefGenVO) {
    return requestClient.post<boolean>(
      `${ServicePrefix}/${MODULAR}/generatorCode`,
      params,
    );
  }

  export async function importCheck(tableNames: string[]) {
    return requestClient.post<boolean>(
      `${ServicePrefix}/${MODULAR}/importCheck`,
      tableNames,
    );
  }
  export async function importTable(
    params: DefGenTableModel.DefGenTableImportVO,
  ) {
    return requestClient.post<boolean>(
      `${ServicePrefix}/${MODULAR}/importTable`,
      params,
    );
  }

  export async function syncField(id: string) {
    return requestClient.post<boolean>(
      `${ServicePrefix}/${MODULAR}/syncField`,
      { id },
      {
        headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
      },
    );
  }

  export async function getDefFileOverrideStrategy() {
    return requestClient.get<Recordable>(
      `${ServicePrefix}/${MODULAR}/getDefFileOverrideStrategy`,
    );
  }

  export async function getFieldTemplate(template: TemplateEnum) {
    return requestClient.get<Recordable>(
      `${ServicePrefix}/${MODULAR}/getFieldTemplate?template=${template}`,
    );
  }

  export async function detail(id: string) {
    return requestClient.get<DefGenTableModel.DefGenTableResultVO>(
      `${ServicePrefix}/${MODULAR}/detail`,
      { params: { id } },
    );
  }

  export const pageTableRequest = async (
    pageQuery: PageParams<DefGenTableModel.DefGenTablePageQuery>,
  ): Promise<UserPageRes> => {
    // 总数据
    const totalList = await selectTableList(pageQuery);

    const list = totalList.filter((item) => {
      const { name, comment } = pageQuery.model;
      if (name && !item.name?.includes(name)) {
        return false;
      }
      if (comment && !item.comment?.includes(comment)) {
        return false;
      }
      return true;
    });

    // 获取请求参数
    const { current, size } = pageQuery;

    const start = (current - 1) * size;
    let end = start + size;
    if (list.length < end) {
      end = list.length;
    }
    const records = list.slice(start, end);

    // 构造返回结果
    return {
      current: Number(pageQuery.current),
      size: Number(pageQuery.size),
      total: list.length,
      records,
    };
  };

  export const pageRequest = async (
    pageQuery: PageParams<DefGenTableModel.DefGenTablePageQuery>,
  ): Promise<UserPageRes> => {
    return await page(pageQuery);
  };

  export const infoRequest = async (ctx: InfoReq): Promise<UserPageRes> => {
    const { row } = ctx;

    // 请求后台查询数据
    return row;
  };

  export const addRequest = async (req: AddReq) => {
    const { form } = req;
    return await save(form);
  };

  export const delRequest = async (ctx: DelReq) => {
    const { row } = ctx;
    return await remove([row.id]);
  };

  export const removeFn = async (ids: string[]) => {
    return await remove(ids);
  };
}
